package com.elinshaw.pattern.readwritelock;

public class WriteLock implements Lock {

    private final ReadWriteLockImpl readWriteLock;

    public WriteLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        Object monitor = readWriteLock.getMUTEX();
        synchronized (monitor) {
            readWriteLock.setWaitingWriters(readWriteLock.getWaitingWriters() + 1);
            try {
                while (readWriteLock.getReadingReaders() > 0 || readWriteLock.getWritingWriters() > 0) {
                    monitor.wait();
                }
            } finally {
                readWriteLock.setWaitingWriters(readWriteLock.getWaitingWriters() - 1);
            }
            readWriteLock.setWritingWriters(readWriteLock.getWritingWriters() + 1);
        }
    }

    @Override
    public void unLock() {
        Object monitor = readWriteLock.getMUTEX();
        synchronized (monitor) {
            readWriteLock.setWritingWriters(readWriteLock.getWritingWriters() - 1);
            //reade线程获得更多机会
            readWriteLock.setPreferWriter(false);
            monitor.notifyAll();
        }
    }

}
